import redis
import json
from typing import Dict, Callable
from typing import Dict, Any
from config.redis_config import redis_config  # 从配置文件读Redis参数

class DataCache:
    def __init__(self):
        # 连接Redis
        self.client = self._init_redis()
        self.cache_key = "edge_data_cache"  # 缓存的键名
        self.max_cache_size = 1000  # 最多存1000条
        self.max_retry = 3  # 最多重试3次

    def _init_redis(self) -> redis.Redis:
        """初始化Redis连接，处理连接失败"""
        try:
            client = redis.Redis(
                host=redis_config["host"],
                port=redis_config["port"],
                db=redis_config["db"],
                decode_responses=False,  # 保留二进制
                socket_timeout=5
            )
            client.ping()  # 测试连接
            return client
        except redis.ConnectionError:
            raise ConnectionError(f"Redis连不上，请检查服务是否启动，配置：{redis_config}")

    def cache_data(self, data: Dict[str, Any]) -> None:
        """缓存数据到Redis，超上限则删最早的"""
        try:
            current_size = self.client.llen(self.cache_key)
            if current_size >= self.max_cache_size:
                self.client.lpop(self.cache_key)  # 删最早的
                print(f"缓存满了，删了1条旧数据，现在有{current_size}条")

            # 转成JSON字符串存进去
            data_str = json.dumps(data).encode("utf-8")
            self.client.rpush(self.cache_key, data_str)
            print(f"数据缓存成功，现在共{self.client.llen(self.cache_key)}条")

        except Exception as e:
            raise RuntimeError(f"缓存失败：{e}")

    def retry_forward(self, forward_func: Callable[[Dict[str, Any]], bool]) -> None:
        """重试转发缓存的数据"""
        print(f"开始转发，当前缓存{self.client.llen(self.cache_key)}条")
        retry_count = 0

        while self.client.llen(self.cache_key) > 0 and retry_count < self.max_retry:
            # 取最早的一条
            cached_data = self.client.lpop(self.cache_key)
            if not cached_data:
                break

            # 解析数据
            try:
                parsed_data = json.loads(cached_data.decode("utf-8"))
            except json.JSONDecodeError:
                print("数据格式错了，跳过")
                continue

            # 尝试转发
            try:
                success = forward_func(parsed_data)
                if success:
                    print(f"转发成功：{parsed_data}")
                    retry_count = 0  # 成功了就重置重试次数
                else:
                    retry_count += 1
                    print(f"转发失败（第{retry_count}次），重新缓存")
                    self.client.rpush(self.cache_key, cached_data)
                    if retry_count >= self.max_retry:
                        print(f"重试{self.max_retry}次都失败，停了")
                        break
            except Exception as e:
                retry_count += 1
                print(f"转发出错（第{retry_count}次）：{e}，重新缓存")
                self.client.rpush(self.cache_key, cached_data)
                if retry_count >= self.max_retry:
                    print("重试够了，停了")
                    break

# 本地测试
if __name__ == "__main__":
    try:
        cache = DataCache()
        # 缓存两条测试数据
        cache.cache_data({"temperature": 25.3, "device_id": "sensor_001"})
        cache.cache_data({"temperature": 26.1, "device_id": "sensor_002"})

        # 模拟转发函数（成功返回True）
        def mock_forward(data):
            print(f"模拟发到云端：{data}")
            return True

        # 重试转发
        cache.retry_forward(mock_forward)
    except Exception as e:
        print("测试出错：", e)